/*
*	File: Vector.cpp
*	Date: 12/05/2011
*	Author: Ivan Gao
*	Desc:
*/
#include "Vector.h"
SVector3::SVector3 () : x (0.0f), y (0.0f), z (0.0f)
{

}

SVector3::SVector3 (float _x, float _y, float _z) : x (_x), y (_y), z (_z)
{

}

SVector3::SVector3 (const SVector3 & rVector) : x (rVector.x), y (rVector.y), z (rVector.z)
{

}

SVector3::~SVector3 ()
{

}

SVector3 & SVector3::operator = (const SVector3 & rVector)
{
	x = rVector.x;
	y = rVector.y;
	z = rVector.z;
	return *this;
}

SVector3 & SVector3::operator *= (float scale)
{
	x *= scale;
	y *= scale;
	z *= scale;
	return * this;
}

SVector3 & SVector3::operator /= (float scale)
{
	float invScale = 1.0f / scale;
	x *= invScale;
	y *= invScale;
	z *= invScale;
	return *this;
}

SVector3 & SVector3::operator += (const SVector3 & rVector)
{
	x += rVector.x;
	y += rVector.y;
	z += rVector.z;
	return *this;
}

SVector3 & SVector3::operator -= (const SVector3 & rVector)
{
	x -= rVector.x;
	y -= rVector.y;
	z -= rVector.z;
	return *this;
}

SVector3 & SVector3::operator - (void)
{
	x = -x;
	y = -y;
	z = -z;
	return *this;
}

float SVector3::GetLength() const
{
	float len = (float)sqrt (x * x + y * y + z * z);
	return len;
} // GetLength

float SVector3::operator [] (int nIdx)
{
	return v[nIdx];
}

float SVector3::operator [] (int nIdx) const
{
	return v[nIdx];
}

SVector3 & SVector3::Normalize()
{
	float len = sqrt (x * x + y * y + z * z);
	float invLen = 1.0f / len;
	x *= invLen;
	y *= invLen;
	z *= invLen;
	return *this;
} // Normalize

float SVector3::DotProduct(const SVector3 & rcVector)
{
	float product = x * rcVector.x + y * rcVector.y + z * rcVector.z;
	return product;
} // DotProduct

SVector3 & SVector3::CrossProduct (const SVector3 & rcVector)
{
	float nx = y * rcVector.z - z * rcVector.y;
	float ny = z * rcVector.x - x * rcVector.z;
	z = x * rcVector.y - y * rcVector.x;
	x = nx;
	y = ny;
	return * this;
}

void SVector3::SetValue(float _x, float _y, float _z)
{
	x = _x;
	y = _y;
	z = _z;
}

bool SVector3::operator == (const SVector3 & rcVector)
{
	return (x == rcVector.x && y == rcVector.y && z == rcVector.z);
}

bool SVector3::operator != (const SVector3 & rcVector)
{
	return (x != rcVector.x || y != rcVector.y || z != rcVector.z);
}

SVector3 operator + (const SVector3 & rFirst, const SVector3 & rSecond)
{
	return SVector3 (rFirst.x + rSecond.x, rFirst.y + rSecond.y, rFirst.z + rFirst.z);
}

SVector3 operator - (const SVector3 & rFirst, const SVector3 & rSecond)
{
	return SVector3 (rFirst.x - rSecond.x, rFirst.y - rSecond.y, rFirst.z - rSecond.z);
}

SVector3 operator * (const SVector3 & rcVector, float scale)
{
	return SVector3 (rcVector.x * scale, rcVector.y * scale, rcVector.z * scale);
}

SVector3 operator / (const SVector3 & rcVector, float scale)
{
	float invScale = 1.0f / scale;
	return SVector3 (rcVector.x * invScale, rcVector.y * invScale, rcVector.z * invScale);
}

bool operator == (const SVector3 & rFirst, const SVector3 & rSecond)
{
	return (rFirst.x == rSecond.x && rFirst.y == rSecond.y && rFirst.z == rSecond.z);
}

bool operator != (const SVector3 & rFirst, const SVector3 & rSecond)
{
	return (rFirst.x != rSecond.y || rFirst.y != rSecond.y || rFirst.z != rSecond.z);
}

float DotProduct (const SVector3 & rFirst, const SVector3 & rSecond)
{
	float len = rFirst.x * rSecond.x + rFirst.y * rSecond.y + rFirst.z * rSecond.z;
	return len;
}

SVector3 CrossProduct (const SVector3 & rFirst, const SVector3 & rSecond)
{
	return SVector3 (rFirst.y * rSecond.z - rFirst.z * rSecond.y,
		rFirst.z * rSecond.x - rFirst.x * rSecond.z,
		rFirst.x * rSecond.y - rFirst.y * rSecond.x);
}

SVector3 Normalize (const SVector3 & rcVector)
{
	float len = rcVector.GetLength();
	float invLen = 1.0f / len;
	return SVector3 (rcVector.x * invLen, rcVector.y * invLen, rcVector.z * invLen);
}
